#pragma once
#include <Rz/IObject.h>
#include <Rz/EnumFlags.h>
#include "IStream.h"
#include "IStreamLineOperations.h"

namespace Rz { namespace IO {

enum class FileAccess
{
	Read = RZ_DEFINE_ENUMFLAG(0),
	Write = RZ_DEFINE_ENUMFLAG(1),
	ReadWrite = Read | Write
};

enum class FileMode
{
	CreateNew,	
	Create,
	Open,
	OpenOrCreate,
	Truncate,	
	Append		
};

RZ_MARK_AS_ENUMFLAGS(FileAccess);

class FileStream :
	virtual public IObject,
	virtual public IStream,
	virtual public IStreamLineOperations
{
	public:
		RZ_RTTI(Rz::IO, FileStream);
		RZ_RTTI_IMPLEMENTS(IObject, IStream, IStreamLineOperations);
		RZ_RTTI_END;

		FileStream();
		FileStream(const String& filename);
		FileStream(const String& filename, FileMode mode);
		FileStream(const String& filename, FileMode mode, FileAccess access);
		virtual ~FileStream();

		void Open(const String& filename);
		void Open(const String& filename, FileMode mode);
		void Open(const String& filename, FileMode mode, FileAccess access);

		bool IsEndOfFile() const;

		virtual size_t Read(byte_t* buffer, size_t size) const override;
		virtual String ReadLine() const override;
		virtual void Write(const byte_t* buffer, size_t size) override;
		virtual void WriteLine(const String& str) override;

		virtual void Seek(size_t position) override;
		virtual size_t GetPosition() const override;
		virtual size_t GetLength() const override;

		virtual bool IsOpened() const override;

		virtual bool CanSeek() const override;
		virtual bool CanRead() const override;
		virtual bool CanWrite() const override;

		virtual void Close() override;

	private:
		FILE* _stream;
		String _filename;
		FileMode _fileMode;
		FileAccess _fileAccess;
};

} }
